package log

import (
	"fmt"
	"os"
	"sync"
	"sync/atomic"
	"time"
)

type logFile struct {
	mu       sync.Mutex
	dir      string
	name     string
	file     *os.File
	lastHour int32
}

const cacheSize = 64 * 1024 // 64KB

func NewLogFile(dir, name string) *logFile {
	l := &logFile{
		dir:      dir,
		name:     name,
		lastHour: int32(time.Now().Hour()),
	}
	l.rotateFileLocked()
	return l
}

func (l *logFile) rotateFileLocked() {
	if _, err := os.Stat(l.dir); os.IsNotExist(err) {
		_ = os.MkdirAll(l.dir, 0755)
	}
	if l.file != nil {
		_ = l.file.Close()
	}

	fileName := fmt.Sprintf("%s/%s-%s.log", l.dir, l.name, time.Now().Format("2006-01-02-15"))
	file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		return
	}

	l.file = file
}

func (l *logFile) Write(p []byte) (int, error) {
	currentHour := int32(time.Now().Hour())
	if atomic.LoadInt32(&l.lastHour) == currentHour {
		return l.file.Write(p)
	}

	l.mu.Lock()
	defer l.mu.Unlock()

	// double check
	if atomic.LoadInt32(&l.lastHour) != currentHour {
		l.rotateFileLocked()
		atomic.StoreInt32(&l.lastHour, currentHour)
	}
	return l.file.Write(p)
}
